package com.allenkerr.util;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.*;

/**
 * Created by 小柯 on 17/7/7.
 */
public class ImageUtils {

    /**
     * 改变图片大小
     *
     * @param source
     * @param width
     * @param height
     * @param b
     * @return
     */
    public static BufferedImage thumb(BufferedImage source, int width, int height, boolean b) {

        int type = source.getType();
        BufferedImage target = null;
        double sx = (double) width / source.getWidth();
        double sy = (double) height / source.getHeight();

        if (b) {
            if (sx > sy) {
                sx = sy;
                width = (int) (sx * source.getWidth());
            } else {
                sy = sx;
                height = (int) (sy * source.getHeight());
            }
        }

        if (type == BufferedImage.TYPE_CUSTOM) { // handmade
            ColorModel cm = source.getColorModel();
            WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
            boolean alphaPremultiplied = cm.isAlphaPremultiplied();
            target = new BufferedImage(cm, raster, alphaPremultiplied, null);
        } else
            target = new BufferedImage(width, height, type);

        Graphics2D g = target.createGraphics();

        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
        g.dispose();
        return target;
    }

    public static void waterMark(String imgPath, String markPath, int x, int y, float alpha) {
        try {
            // 加载待处理图片文件
            Image img = ImageIO.read(new File(imgPath));

            BufferedImage image = new BufferedImage(img.getWidth(null),
                    img.getHeight(null), BufferedImage.TYPE_INT_RGB);
            Graphics2D g = image.createGraphics();
            g.drawImage(img, 0, 0, null);

            // 加载水印图片文件
            Image src_biao = ImageIO.read(new File(markPath));
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            g.drawImage(src_biao, x, y, null);
            g.dispose();

            // 保存处理后的文件
            FileOutputStream out = new FileOutputStream(imgPath);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(image);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void textMark(String imgPath, String text, Font font, Color color, int x, int y, float alpha) {
        try {
            Font Dfont = (font == null) ? new Font("宋体", 20, 13) : font;

            Image img = ImageIO.read(new File(imgPath));

            BufferedImage image = new BufferedImage(img.getWidth(null),
                    img.getHeight(null), BufferedImage.TYPE_INT_RGB);

            Graphics2D g = image.createGraphics();

            g.drawImage(img, 0, 0, null);
            g.setColor(color);
            g.setFont(Dfont);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            g.drawString(text, x, y);
            g.dispose();
            FileOutputStream out = new FileOutputStream(imgPath);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(image);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 从 filePath 获取 BufferedImage
     *
     * @param filePath
     * @return BufferedImage
     */
    public static BufferedImage getBufferedImage(String filePath) {
        File file = new File(filePath);
        return getBufferedImage(file);
    }

    /**
     * 从 File 获取 BufferedImage
     *
     * @param file
     * @return BufferedImage
     */
    public static BufferedImage getBufferedImage(File file) {
        try {
            BufferedImage image = ImageIO.read(file);
            return image;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Deprecated
    public static BufferedImage readImage(String filename) {
        BufferedImage sourceImage = null;
        if (filename.endsWith(".png") || filename.endsWith(".PNG")) {
            sourceImage = ImageUtils.readPNGImage(filename);
        } else if (filename.endsWith(".jpg") || filename.endsWith(".JPG") ||
                filename.endsWith(".jpeg") || filename.endsWith(".JPEG")) {
            sourceImage = ImageUtils.readJPEGImage(filename);
        }
        return sourceImage;
    }

    @Deprecated
    public static BufferedImage readJPEGImage(String filename) {
        try {
            InputStream imageIn = new FileInputStream(new File(filename));

            // 得到输入的编码器，将文件流进行jpg格式编码
            JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(imageIn);

            // 得到编码后的图片对象
            BufferedImage sourceImage = decoder.decodeAsBufferedImage();

            return sourceImage;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ImageFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Deprecated
    public static BufferedImage readPNGImage(String filename) {
        try {
            File inputFile = new File(filename);
            BufferedImage sourceImage = ImageIO.read(inputFile);
            return sourceImage;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ImageFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * RGB值 --> 灰度值(灰度值由一个0到255的整数表示)
     * 灰度图相关算法（R = red， G = green， B = blue）
     * 1.浮点算法：Gray = R*0.3+G*0.59+B*0.11
     * 2.整数方法：Gray = (R*30+G*59+B*11)/100
     * 3.移位方法：Gray = (R*76+G*151+B*28)>>8;
     * 4.平均值法：Gray =（R+G+B）/3;
     * 5.仅取绿色：Gray = G;
     *
     * @param rgb
     * @return
     */
    public static int rgbToGrey(int rgb) {
        int _red = (rgb >> 16) & 0xFF;
        int _green = (rgb >> 8) & 0xFF;
        int _blue = (rgb) & 0xFF;
        return (30 * _red + 59 * _green + 11 * _blue) / 100;
    }

    /**
     * 计算平均值
     *
     * @param pixels
     * @return int average
     */
    public static int average(int[][] pixels) {
        float sum = 0;
        int length = 0;
        for (int i = 0; i < pixels.length; i++) {
            for (int j = 0; j < pixels[i].length; j++) {
                sum += pixels[i][j];
                length++;
            }
        }
        return (int) sum / length;
    }
}